#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Thibauld Favre <tfavre@gmail.com>
#
# Author:
#  Thibauld Favre
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA

import os
import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
from smcagent import SMCAgent
import webbrowser
import signal
from optparse import OptionParser

api_key = 'd0Iu84Rp2qSz70aE'

def stop(*args):  SMCAgent.listen = False
def smc_gui(): 
    app = QApplication(sys.argv) 
    w = SMCGui() 
    w.show()
    sys.exit(app.exec_())

def smc_nogui():
    a = SMCAgent(api_key)
    registered = True
    try:
        if not a.checkToken():
            registered = False
            import webbrowser
            webbrowser.open(a.getAuthUrl(), True, True)
            registered = a.register()
        if registered:
            a.run()
        else:
            print "Device registration timed out. Please reconnect to register this machine..."
    except IOError, e:
        print e
            
class AgentThread(QThread):
    def __init__(self,parent=None):
        self.agent = SMCAgent(api_key)
        self.registered = True
        self.registration_required = False
        self.connection_error = False
        self.registration_error = False
        QThread.__init__(self,parent)

    def getAuthUrl(self):
        return self.agent.getAuthUrl()

    def run(self, parent=None):
        try:
            if not self.agent.checkToken():
                self.registered = False
                self.registration_required = True
                self.registered = self.agent.register()
            if self.registered:
                self.registration_required = False
                self.agent.run()
            else:
                self.registration_error = True
        except IOError, e:
            self.connection_error = True

    def connect(self):
        self.registration_error = False
        self.connection_error = False
        if not SMCAgent.listen:
            self.start()

    def disconnect(self):
        if SMCAgent.listen:
            SMCAgent.listen = False

class SMCGui(QSystemTrayIcon): 
    def __init__(self, *args): 
        QSystemTrayIcon.__init__(self, *args)

        # create objects
        self.agent = AgentThread(self)
        self.icon_on = QIcon(QString('/usr/share/savemyconf-client/icons/smc-client-on.png'))
        self.icon_off = QIcon(QString('/usr/share/savemyconf-client/icons/smc-client-off.png'))
        self.icon_connect = QIcon(QString('/usr/share/savemyconf-client/icons/smc-client-connect.png'))
        self.icon_disconnect = QIcon(QString('/usr/share/savemyconf-client/icons/smc-client-disconnect.png'))
        self.icon_quit = QIcon(QString('/usr/share/savemyconf-client/icons/smc-client-quit.png'))
        self.icon_timer = QTimer(self)
        self.registration_timer = QTimer(self)
        self.setIcon(self.icon_off)
        self.popmenu = QMenu("SaveMyConf")
        self.action_connect = QAction(self.icon_connect,"Connect",self)
        self.action_disconnect = QAction(self.icon_connect,"Disconnect",self)
        self.action_disconnect.setEnabled(False)
        self.action_quit = QAction(self.icon_quit,"Quit",self)
        self.popmenu.addAction(self.action_connect)
        self.popmenu.addAction(self.action_disconnect)
        self.popmenu.addAction(self.action_quit)

        # create connection
        self.connect(self.action_connect, SIGNAL("triggered()"), self.connectAgent)
        self.connect(self.action_disconnect, SIGNAL("triggered()"), self.disconnectAgent)
        self.connect(self.action_quit, SIGNAL("triggered()"), self.quit)
        self.connect(self.icon_timer, SIGNAL("timeout()"), self.toggle_icon)
        self.connect(self.registration_timer, SIGNAL("timeout()"), self.disconnectAgent)
        self.connect(self, SIGNAL("messageClicked()"), self.launchBrowser)
        self.connect(self, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"),self.showPopupMenu)
        self.setContextMenu(self.popmenu)
        self.show()
        self.connectAgent()
 
    def showPopupMenu(self,reason):
        if reason==QSystemTrayIcon.Context or reason==QSystemTrayIcon.Trigger:
            g = self.geometry()
            s = self.popmenu.sizeHint()
            self.popmenu.setGeometry(g.x(),g.y()+g.height(),s.width(),s.height())
            self.popmenu.show()

    def launchBrowser(self):
        self.registration_timer.stop()
        if not self.agent.registered:
            webbrowser.open(self.agent.getAuthUrl(), True, True)

    def toggle_icon(self):
        if self.agent.registered:
            self.icon_timer.stop()
            self.setIcon(self.icon_on)
            self.showMessage("SaveMyConf","Connected to SaveMyConf",QSystemTrayIcon.Information,2000)
        elif self.agent.registration_required:
            self.agent.registration_required = False
            self.showMessage("SaveMyConf","Authentification needed.\nPlease click on this message to authenticate your PC on SaveMyConf...")
            self.registration_timer.start(15000)
        elif self.agent.connection_error:
            self.disconnectAgent()
            self.showMessage("SaveMyConf","Connexion refused.\nPlease check your internet connection or retry later...",QSystemTrayIcon.Critical,3000)
        elif self.agent.registration_error:
            self.disconnectAgent()
            self.showMessage("SaveMyConf","Device registration timed out.\nPlease reconnect to register this PC...",QSystemTrayIcon.Critical,3000)
        else:
            if self.icon().serialNumber()==self.icon_off.serialNumber():
                self.setIcon(self.icon_on)
            else:
                self.setIcon(self.icon_off)

    def connectAgent(self):
        self.action_connect.setDisabled(True)
        self.icon_timer.start(500)
        self.agent.connect()
        self.action_disconnect.setDisabled(False)
        self.setIcon(self.icon_on)

    def disconnectAgent(self):
        self.icon_timer.stop()
        self.action_disconnect.setDisabled(True)
        self.agent.disconnect()
        self.action_connect.setDisabled(False)
        self.setIcon(self.icon_off)

    def quit(self):
        self.hide()
        self.agent.disconnect()
        self.agent.wait()
        qApp.exit()

if __name__ == "__main__":
    argv = sys.argv[1:]
    signal.signal(signal.SIGINT,stop)
    signal.signal(signal.SIGTERM,stop)
    if argv is None:
        argv = sys.argv
    parser = OptionParser()
    parser.set_usage('savemyconf-client [OPTION]\nExecute savemyconf-client from command-line if you don\'t want to clutter your desktop systray with yet another icon.' )
    parser.add_option('-c','--no-gui', action='store_true', dest='no_gui', default=False, help='do not display an icon in the systray')
    options, args = parser.parse_args()
    if options.no_gui: smc_nogui()
    else: smc_gui()
